#include <REGX52.H>

sbit LCD_RS=P2^6;
sbit LCD_EN=P2^7;
sbit LCD_WR=P2^5;
#define LCD_DataPort P0

/**
  * @brief  LCD1602延时函数，12MHz调用可延时1ms
  * @param  无
  * @retval 无
  */
void LCD_Delay()		//@12.000MHz 1ms
{
	unsigned char i, j;

	i = 2;
	j = 239;
	do
	{
		while (--j);
	} while (--i);
}

void LCD_WriteCommand(unsigned char Command)	//写指令
{
	LCD_RS=0;
	LCD_WR=0;
	LCD_DataPort=Command;
	LCD_EN=1;
	LCD_Delay();	//EN置1后直接置0会出错，延时1ms
	LCD_EN=0;
	LCD_Delay();
}

void LCD_WriteData(unsigned char Data)	//写数据
{
	LCD_RS=1;
	LCD_WR=0;
	LCD_DataPort=Data;
	LCD_EN=1;
	LCD_Delay();	//EN置1后直接置0会出错，延时1ms
	LCD_EN=0;
	LCD_Delay();
}

void LCD_Init(void)	//初始化
{
	LCD_WriteCommand(0x38);	//八位数据接口，两行显示，5*7点阵
	LCD_WriteCommand(0x0C);	//显示开，光标关，闪烁关
	LCD_WriteCommand(0x06);	//数据读写操作后，光标自动加一，画面不动
	LCD_WriteCommand(0x01);	//清屏
}

void LCD_SetCursor(unsigned char Line,unsigned char Column)	//显示字符
{
	if(Line==1)
	{
		LCD_WriteCommand(0x80|(Column-1));	//设置光标位置，0X80选择对应指令，AC选择光标位置
		//选择第一行，根据列减1，第一行第一列为1-1=0，与DDRAM（数据显示区）0x00相对应
	}
	else
	{
		LCD_WriteCommand(0x80|(Column-1)+0x40);	//第二行开头DDRAM地址为0x40
	}
}
	
void LCD_ShowChar(unsigned char Line,unsigned char Column,unsigned char Char)	//显示一个字符
{
	LCD_SetCursor(Line,Column);
	LCD_WriteData(Char);
}

void LCD_ShowString(unsigned char Line,unsigned char Column,unsigned char *String)	//显示字符串
{										//显示字符串要给一个数组，通过指针传递数组首元素地址
	unsigned char i;
	LCD_SetCursor(Line,Column);
	for(i=0;String[i]!='\0';i++)	//输入字符串以“ABC”的形式，
					//char z[]=”ABC”;（等效于char z[]={’A’, ’B’, ’C’, ’\0’};	
	{
		LCD_WriteData(String[i]);
	}
}

/**
  * @brief  返回值=X的Y次方
  */
int LCD_Pow(int X,int Y)
{
	unsigned char i;
	int Result=1;
	for(i=0;i<Y;i++)
	{
		Result*=X;
	}
	return Result;
}

void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)//显示无符号整数
{
	unsigned char i;
	LCD_SetCursor(Line,Column);
	for(i=Length;i>0;i--)
	{
		LCD_WriteData('0'+Number/LCD_Pow(10,i-1)%10);	//将数字每一位从高到低显示
	}
}

void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length)//显示有符号数字
{
	unsigned char i;
	unsigned int Number1;
	LCD_SetCursor(Line,Column);
	if(Number>0)
	{
		LCD_ShowChar(Line,Column,'+');
		Number1=Number;
	}
	else
	{	
		LCD_ShowChar(Line,Column,'-');
		Number1=-Number;
	}
	for(i=Length;i>0;i--)
	{
		LCD_WriteData('0'+Number1/LCD_Pow(10,i-1)%10);	//将数字每一位从高到低显示
	}
}

void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)//显示16进制数字
{
	unsigned char i;
	unsigned char SingleNumber;
	SingleNumber=Number/LCD_Pow(16,i-1)%16;
	LCD_SetCursor(Line,Column);
	for(i=Length;i>0;i--)
	{
		if(SingleNumber<10)
		{
			LCD_WriteData('0'+Number/LCD_Pow(16,i-1)%16);	//将数字每一位从高到低显示
		}
		else if(SingleNumber>=10)
		{
			LCD_WriteData('A'+Number/LCD_Pow(16,i-1)%16-10);	//-10后对应A的ASLL码
		}
	}
}

void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)//显示2进制数字
{
	unsigned char i;
	LCD_SetCursor(Line,Column);
	for(i=Length;i>0;i--)
	{
		LCD_WriteData('0'+Number/LCD_Pow(2,i-1)%2);	//将数字每一位从高到低显示
	}
}